1 module hip.hiprenderer.initializer;
2 import hip.hiprenderer.renderer;
3 
4 public HipRendererType rendererFromString(string str)
5 {
6     import hip.error.handler;
7     switch(str) with(HipRendererType)
8     {
9         case "GL3": return GL3;
10         case "D3D11": return D3D11;
11         case "Metal": return Metal;
12         default:
13         {
14             ErrorHandler.showErrorMessage("Invalid renderer '"~str~"'",
15             `
16                 Available renderers:
17                     GL3
18                     D3D11
19                     Metal
20 
21                 Fallback to GL3
22             `);
23             return GL3;
24         }
25     }
26 }
27 public IHipRendererImpl getRendererWithFallback(HipRendererType type)
28 {
29     import hip.console.log;
30     static HipRendererType[3] getRendererFallback(HipRendererType type)
31     {
32         switch(type) with(HipRendererType)
33         {
34             case GL3: return [GL3, D3D11, Metal];
35             case D3D11: return [D3D11, GL3, None];
36             case Metal: return [Metal, GL3, None];
37             default: return [None, None, None];
38         }
39     }
40     foreach(fallback; getRendererFallback(type))
41     {
42         IHipRendererImpl impl = getRendererImplementation(fallback);
43         if(fallback == HipRendererType.None)
44             break;
45         if(impl !is null)
46             return impl;
47         logln(fallback, " wasn't included in the build, trying next fallback.");
48     }
49     return null;
50 }
51 
52 
53 public HipRendererType getRendererTypeFromVersion()
54 {
55     with(HipRendererType)
56     return HasDirect3D ? D3D11 : HasMetal ? Metal : HasOpenGL ? GL3 : None;
57 }
58 
59 public IHipRendererImpl getRendererImplementation(HipRendererType type)
60 {
61     static IHipRendererImpl getOpenGLRenderer()
62     {
63         static if(HasOpenGL)
64         {
65             import hip.hiprenderer.backend.gl.glrenderer;
66             return new Hip_GL3Renderer();
67         }
68         else return null;
69     }
70     static IHipRendererImpl getDirect3DRenderer()
71     {
72         static if(HasDirect3D)
73         {
74             import hip.hiprenderer.backend.d3d.d3drenderer;
75             return new Hip_D3D11_Renderer();
76         }
77         else return null;
78     }
79     static IHipRendererImpl getMetalRenderer()
80     {
81         static if(HasMetal)
82         {
83             import hip.hiprenderer.backend.metal.mtlrenderer;
84             return new HipMTLRenderer();
85         }
86         else return null;
87     }
88     switch ( type )
89     {
90         case HipRendererType.GL3: return getOpenGLRenderer;
91         case HipRendererType.D3D11: return getDirect3DRenderer;
92         case HipRendererType.Metal: return getMetalRenderer;
93         default: return null;
94     }
95 }
96 
97 immutable(DefaultShader[]) getDefaultFromModule(string mod)()
98 {
99     static if(__traits(compiles, {mixin("import ",mod,";");}))
100     {
101         mixin("static import ", mod, ";");
102         static if(__traits(getMember, mixin(mod), "DefaultShaders"))
103             return mixin(mod,".DefaultShaders");
104     }
105     return [];
106 }
107 
108 /**
109  * Default Shaders are all accessed with
110  * HipDefaultShaders[HipRendererType][HipShaderPresets]
111  */
112 immutable DefaultShader[][] HipDefaultShaders = [
113     HipRendererType.GL3: getDefaultFromModule!"hip.hiprenderer.backend.gl.defaultshaders",
114     HipRendererType.D3D11: getDefaultFromModule!"hip.hiprenderer.backend.d3d.defaultshaders",
115     HipRendererType.Metal: getDefaultFromModule!"hip.hiprenderer.backend.metal.defaultshaders",
116     HipRendererType.None: []
117 ];
118 
119 
120 public Shader newShader(HipShaderPresets shaderPreset, HipRendererType type = HipRendererType.None)
121 {
122     import hip.util.conv:to;
123     import hip.console.log;
124     if(type == HipRendererType.None)
125         type = HipRenderer.getType();
126 
127     Shader ret = HipRenderer.newShader();
128     DefaultShader shaderInfo = HipDefaultShaders[type][shaderPreset];
129 
130     ShaderStatus status = ret.loadShaders(shaderInfo.vSource(), shaderInfo.fSource(), shaderInfo.path~"."~shaderPreset.to!string);
131 
132     if(status != ShaderStatus.SUCCESS)
133         logln("Failed loading shaders with status ", status, " at preset ", shaderPreset, " on "~shaderInfo.path);
134     return ret;
135 }